package com.njitt.bysj.srevice;

import com.njitt.bysj.base.BaseService;
import com.njitt.bysj.bean.PermissionBean;
import com.njitt.bysj.mapper.PermissionBeanMapper;
import com.njitt.bysj.model.EmpModel;
import com.njitt.bysj.utils.AssertUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @description:
 * @author: wyj
 * @time: 2022/3/26 10:14
 */
@Service
public class PermissionService extends BaseService<PermissionBean, Integer> {
    @Resource
    private PermissionBeanMapper permissionMapper;

    public List<Map<String, Object>> selectAllMenu() {
        List<Map<String, Object>> Menu = permissionMapper.queryAllMenu();
        List<Map<String, Object>> allMenu = new ArrayList<>();

        for (Map<String, Object> map : Menu) {
            allMenu.add(map);
        }

        List<Map<String, Object>> rootMenu = new ArrayList<>();
        for (Map<String, Object> nav : allMenu) {
            String pId = String.valueOf(nav.get("pId"));
            if (pId.equals("0")) {
                rootMenu.add(nav);
            }
        }
        for (Map<String, Object> nav : rootMenu) {
            String id = String.valueOf(nav.get("id"));
            List<Map<String, Object>> childList = getChild(id, allMenu);
            nav.put("child", childList);
        }

        return rootMenu;

    }

    private List<Map<String, Object>> getChild(String id, List<Map<String, Object>> allMenu) {
        List<Map<String, Object>> childList = new ArrayList<>();
        for (Map<String, Object> nav : allMenu) {
            String pid = String.valueOf(nav.get("pId"));
            if (id.equals(pid)) {
                childList.add(nav);
            }
        }
        for (Map<String, Object> nav : childList) {
            String tempId = String.valueOf(nav.get("id"));
            nav.put("child", getChild(tempId, allMenu));
        }
        if (childList.size() == 0) {
            return new ArrayList<>();
        }
        return childList;
    }

    public List<Map<String, Object>> roleMenu() {
        List<String> roleType = permissionMapper.queryMidMenu();
        Subject subject = SecurityUtils.getSubject();
        EmpModel empModel = (EmpModel) subject.getPrincipal();  // shiro 取存储的认证信息 获取角色
        empModel.getRoles().forEach(r -> {
            roleType.add(r);
        });
        System.out.println(roleType);
        List<Map<String, Object>> Menu = permissionMapper.queryOperations(roleType);
        System.out.println(Menu);
        List<Map<String, Object>> allMenu = new ArrayList<>();
        for (Map<String, Object> map : Menu) {
            allMenu.add(map);
        }
        List<Map<String, Object>> rootMenu = new ArrayList<>();
        // 将根节点添加进去
        for (Map<String, Object> nav : allMenu) {
            String pId = String.valueOf(nav.get("p_id"));
            if (pId.equals("0")) {
                rootMenu.add(nav);
            }
        }
        for (Map<String, Object> nav : rootMenu) {
            String id = String.valueOf(nav.get("id"));
            List<Map<String, Object>> childList = getChildRole(id, allMenu);
            nav.put("child", childList);
        }
        return rootMenu;
    }

    private List<Map<String, Object>> getChildRole(String id, List<Map<String, Object>> allMenu) {
        List<Map<String, Object>> childList = new ArrayList<>();
        for (Map<String, Object> nav : allMenu) {
            String pid = String.valueOf(nav.get("p_id"));
            if (id.equals(pid)) {
                childList.add(nav);
            }
        }
        for (Map<String, Object> nav : childList) {
            String tempId = String.valueOf(nav.get("id"));
            nav.put("child", getChildRole(tempId, allMenu));

        }
        if (childList.size() == 0) {
            return new ArrayList<>();
        }
        return childList;
    }


    public Map<String, Object> queryAllModule() {
        /**
         * @description:展示树形结构
         * @return:  * @param
         * @author:
         * @time: 2022/4/25 23:44
         */
        List<PermissionBean> list = permissionMapper.queryAllModule();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "success");
        map.put("data", list);
        map.put("count", list.size());
        return map;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @SuppressWarnings("AlibabaTransactionMustHaveRollback")
    public void addModule(PermissionBean permissionBean) {
        // 判断层级
        Integer isType = permissionBean.getIsType().intValue();
        AssertUtil.isTrue(null == isType || !(isType == 1 || isType == 2 || isType == 3), "菜单层级不合法");
        AssertUtil.isTrue(StringUtils.isBlank(permissionBean.getTitle()), "标题名称不能为空");
        //同一蹭几下模块名称唯一
        AssertUtil.isTrue(null != permissionMapper.queryModuleByGradeAndModuleName(isType, permissionBean.getTitle()), "结构名称不合法");

        // 二级菜单路径 不能为空
        if (isType == 2 || isType == 3) {
            AssertUtil.isTrue(null == permissionBean.getHref(), "路径不能为空");
            //同级别下路径不可重复
            AssertUtil.isTrue(null != permissionMapper.queryModulesByGradeAndUrl(isType, permissionBean.getHref()), "路径不合法");
        }
        if (isType == 1) {
            permissionBean.setpId(1);
        }
        if (isType != 1) {
            AssertUtil.isTrue(null == permissionBean.getpId(), "父级菜单不能为空");
            AssertUtil.isTrue(null == permissionMapper.selectByPrimaryKey(permissionBean.getpId()), "父级菜单不合法");
        }
        AssertUtil.isTrue(StringUtils.isBlank(permissionBean.getResourceType()), "资源为空");

        permissionBean.setStatus((byte) 0);
        permissionBean.setTarget("_self");
        permissionBean.setCreateTime(new Date());
        permissionBean.setUpdatetime(new Date());
        AssertUtil.isTrue(permissionMapper.insertSelective(permissionBean) < 1, "添加资源失败");
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @SuppressWarnings("AlibabaTransactionMustHaveRollback")
    public void updateModule(PermissionBean permissionBean) {
        // 1. 参数校验  id 不为空且数据存在
        AssertUtil.isTrue(null == permissionBean.getId(), "待更新记录不存在 ");
        PermissionBean temp = permissionMapper.selectByPrimaryKey(permissionBean.getId());
        // 判断记录是否存在
        AssertUtil.isTrue(null == temp, "待更新记录不存在 ");
        // 判断层级 isType
        Integer isType = permissionBean.getIsType().intValue();
        AssertUtil.isTrue(null == isType || !(isType == 0 || isType == 1 || isType == 2), "菜单层级不合法");
        // 模块名称
        AssertUtil.isTrue(StringUtils.isBlank(permissionBean.getTitle()), "模块名称不能为空");
        // 通过名称去查寻
        temp = permissionMapper.queryModuleByGradeAndModuleName(isType, permissionBean.getTitle());
        if (temp != null) {
            AssertUtil.isTrue(!(temp.getId().equals(permissionBean.getId())), "该层级下菜单名字已经存在");
        }
        // 地址url 判断是否是二级菜单
        if (isType == 2) {
            AssertUtil.isTrue(StringUtils.isBlank(permissionBean.getHref()), "href 不能为空");
            //通过层级与 url 查询资源对昂
            temp = permissionMapper.queryModulesByGradeAndUrl(isType, permissionBean.getHref());
            if (temp != null) {
                AssertUtil.isTrue(!(temp.getId().equals(permissionBean.getId())), "该层级下菜单url已经存在");
            }
        }
        // 权限码
        AssertUtil.isTrue(StringUtils.isBlank(permissionBean.getResourceType()), "权限码不能为空");

        permissionBean.setUpdatetime(new Date());
        // 执行更新
        AssertUtil.isTrue(permissionMapper.updateByPrimaryKeySelective(permissionBean) < 1, "修改资源失败");
    }
    @Transactional(propagation = Propagation.REQUIRED)
    @SuppressWarnings("AlibabaTransactionMustHaveRollback")
    public void deleteModule(Integer id) {
        AssertUtil.isTrue(null == id, "待删除记录不存在");
        PermissionBean temp = permissionMapper.selectByPrimaryKey(id);
        AssertUtil.isTrue(temp == null, "待删除记录不存在 ");
        // 判断是否存在子记录  将id 当作父id 查询资源 记录
        Integer count = permissionMapper.queryByPid(id);
        // 如果存在子记录 则不可删除
        AssertUtil.isTrue(count > 0, "该资源存在子记录不可删除");
        Integer integer = permissionMapper.deleteByPrimaryKey(id);
      AssertUtil.isTrue(integer <1,  "删除失败");
    }
}

